package no.uio.ifi.cop.parse.formula;

import java.util.Map;
import java.util.HashMap;

import no.uio.ifi.cop.cl.Term;
import no.uio.ifi.cop.cl.Constant;
import no.uio.ifi.cop.cl.Variable;

/**
 * TermFactory creates Constants and Variables.
 *
 * We have to make sure that Constants are not duplicated
 * since we compare constants by pointer comparison, this
 * class makes sure we only have one constant of 'each' kind.
 *
 * I.e. if constant1.equals(constant2) they both point to the
 * same object, Variables are a bit different, we often want
 * new variables to be different objects in order to clone
 * terms without destroying them once the old terms gets 
 * instantiated.
 *
 *
 * @version 1.0
 * @author bjarneh@ifi.uio.no
 */

public class TermFactory{

    private static int freshCnt = 1;
    private static Map<String, Constant> constants;
    
    // this is horrible, but java.util.Set does not
    // have a method of retrieval to ensure same object-ref
    private static Map<String, String> predicates;

    static{
        init();
    }

    private TermFactory(){}

    private static void init(){
        constants  = new HashMap<String, Constant>();
        predicates = new HashMap<String, String>();
    }

    // clean up
    public static void reset(){
        freshCnt = 1;
        init();
    }

    // if not present add it..
    public static Constant getConstant(String id){

        Constant c = constants.get(id);

        if( c == null ){
            c = new Constant( id );
            constants.put( id, c );
        }

        return c;
    }

    public static Constant getFreshConstant(){

        String constantId;
        Constant c;

        do{
            //TODO check out why f_%d generated some freeaky results..
            constantId = String.format("n%d", freshCnt );
            c = constants.get( constantId );
            freshCnt++;
        }while( c != null );

        c = new Constant( constantId );

        return c;
    }

    public static Variable getVariableCopy(String id){
        String copyId = new String( id );
        return new Variable( copyId );
    }

    // all predicates with identical ID should have
    // the same object to utilize == instead of .equals
    public static String getPredicateId(String id){

        String _id = predicates.get(id);
        
        if( _id == null ){
            _id = id;
            predicates.put(_id, _id);
        }

        return _id;
    }
}
